local skynet = require"skynet"
local PlayerPlane = require "PlayerPlane"
local EnemyPlane = require "EnemyPlane"
local FitPlane = require "FitPlane"
local Bullet = require "Bullet"
local PlaneCfg = require "PlaneCfg"
local PlaneTypeCfg = require "PlaneTypeCfg"
local PlaneLevelCfg = require "PlaneLevelCfg"
local FitPlaneCfg = require "FitPlaneCfg"

local BulletCfg = require "BulletCfg"
local BulletTypeCfg = require "BulletTypeCfg"
local CollisionTool = require "CollisionTool"

local random = math.random
local randomseed = math.randomseed
local string = string
local tconcat = table.concat
local PokeServer = {}
local PokeServer_mt = {__index=PokeServer}
local maxplayersize = 2;

local function cancelable_timeout( ti,func)
	local function cb( )
		if func then
			func()
		end
	end
	local function cancel( )
		func = nil
	end
	skynet.timeout(ti,cb)
	return cancel
end

function PokeServer:ctor( users )
	self._roomid = null;
	self._users = users			--参与的玩家
	self._step = 0;
	self._stepData = {}
	self._playerplane = {}		--玩家的飞机
	self._fitplane = {}			--合体机的飞机
	self._enemyplane = {}		--敌人的飞机
	self._bullet = {}			--子弹的数组
	self._newbullet = {}		--新增的子弹数组
	
	self._playerplaneinx = 0;
	self._enemyinx = 0;
	self._bulletinx = 0;
	self._fitplaneinx = 0;		--合体飞机的idx
	
	self._nextsteptime = 200;
	
	self._playerLoadStates = {}
	maxplayersize = #users
	
	for i = 1, maxplayersize do
		self._playerLoadStates[i] = false;
	end
	
	self.stepcount = 4;			-- 最大关卡数
	self.strongcount = 0;		-- 循环次数
	
	-- 是否开始下一波
	self._bnextstep = false;
	self._bhavemove = false;
	self._bhaveNewBullet = false;
end

function PokeServer:start(roomid)
	self._roomid = roomid
	self:initPlane()
	self:initLevelData()
	self:sendAllPlayerReady()
	self._game_over = false
	self._game_status = 1
end

-- 重连游戏 
function PokeServer:relink(pos, player)
	print("PokeServer relink " .. pos)
	-- 发送玩家数据
	self._users[pos] = player
	-- 发送游戏开始
	self._users[pos]:sendGameStart()
	self._users[pos]:sendInitPlane(self._playerplane)
	-- 发送游戏数据
	self._users[pos]:sendGameData(self._enemyplane, self._bullet, self._fitplane)
end

function PokeServer:initPlane()
	-- 玩家飞机
	local sx = 375 - (maxplayersize - 1) * 120 / 2;
	for i = 1, maxplayersize do
		self._playerplaneinx = self._playerplaneinx + 1;
		local playerplane = PlayerPlane.new(self._playerplaneinx)
		local xi = sx + (i - 1) * 120;
		local pos = {
			nXpos = xi,
			nYpos = 200,
		}
		playerplane:setPositon(pos);
		table.insert(self._playerplane, playerplane);
	end
	
end

-- 加载关卡数据
function PokeServer:initLevelData()
	-- 加载关卡数据
	local stepc = 1
	for stepc = 1, self.stepcount do
		local leveldata = require("level_data_" .. stepc);
		local planedata = require("plane_type_" .. stepc);
		if leveldata then
			local data = {}
			for i, level in pairs(leveldata) do
				local ldata = {}
				ldata.cnt = level.cnt
				ldata.planetype = planedata[level.planetype].actiontype
				ldata.plane = PlaneCfg[level.plane].planetype
				table.insert(data, ldata)
			end
			self._stepData[stepc] = data
		end
	end
	print("11111")
	table.print(self._stepData);
end

function PokeServer:gameStart()
	-- 开始游戏
	for i = 1,maxplayersize do 
		self._users[i]:sendGameStart()
		self._users[i]:sendInitPlane(self._playerplane)
	end
	self:gameLoop();
	local t = cancelable_timeout(100,function()
		self._bnextstep = true;	
	end)
end

function PokeServer:sendAllPlayerReady()
	for i = 1, maxplayersize do 
		if self._users[i] then
			self._users[i]:sendAllPlayerReady()
		end
	end
end

-- 玩家加载完成，全部加载完成，则开始游戏
function PokeServer:setPlayerReadyStates(pos, data)
	if self._playerLoadStates[pos] == false then
		self._playerLoadStates[pos] = true;
		local loadfinishcnt = 0;
		for i = 1, maxplayersize do
			if self._playerLoadStates[i] then
				loadfinishcnt = loadfinishcnt  + 1;
			end
		end
		if loadfinishcnt == maxplayersize then
			self:gameStart();
		end
	end
end

function PokeServer:exit()
	--房间状态回归
	for i = 1, maxplayersize do
		self._playerLoadStates[i] = false;
	end
	self._step = 0;
	self._stepData = {}
	self._playerplane = {}		--玩家的飞机
	self._enemyplane = {}		--敌人的飞机
	self._bullet = {}			--子弹的数组
	
	if self._cancel then
		self._cancel()
	end
end

--游戏循环
function PokeServer:gameLoop()
	-- 游戏loop
	-- 检测合体
	self:startCheckFit();
	-- 移动
	self:startMove();
	-- 检测碰撞
	self:startCheckCollision();
	-- 发射子弹
	self:startFileBullet();
	-- 执行下一波的开始
	self:startNextStep();
	-- 同步数据
	self:sendGameData();
	-- 判断游戏是否结束
	local bEnd = self:judgeEnd();
	if bEnd then
		print(" game over !!!")
		self:gameOver();
	else 
		self._cancel = cancelable_timeout(2,function()
			self:gameLoop()			
		end)
	end
end

function PokeServer:judgeEnd()
	for i, plane in pairs(self._playerplane) do
		if not plane:isOut() then
			return false;
		end
	end
	return true;
end

-- 发射子弹
function PokeServer:startFileBullet()
	-- 玩家的子弹
	local playerbullet = {}
	-- 合体机发射子弹
	for i,fitplane in pairs(self._fitplane) do
		if fitplane:isFire() then
			self._bulletinx = self._bulletinx + 1
			local bullet = Bullet.new(self._bulletinx)
			local info = fitplane:getInfo();
			local pos = {
				x = info.posX,
				y = info.posY + info.height + 30,
			}
			local endpos = {
				x = info.posX, 
				y = 1650,
			}	
			bullet:setPositon(pos);
			bullet:setEndPositon(endpos);
			bullet:setType(2);
			bullet:setBulletData(BulletCfg[1].bullettype)
			bullet:setFitBulletIdx(fitplane:getInfo().idx)
			local selfplaneaction = {}
			for ia, action in pairs(BulletTypeCfg[1].actiontype) do
				local ta = {
					actiontype = action.actionenum,
					startpos = { nXpos = action.startpos.x, nYpos = action.startpos.y },
					endpos = { nXpos = action.endpos.x, nYpos = action.endpos.y },
					nangle = action.angle,
				}
				table.insert(selfplaneaction, ta)
			end
			if selfplaneaction and #selfplaneaction > 0 then
				selfplaneaction[1].startpos = { nXpos = pos.x, nYpos = pos.y }
				selfplaneaction[1].endpos = { nXpos = pos.x, nYpos = 1400 }
			end
			bullet:setActionArray(selfplaneaction)
			table.insert(self._bullet, bullet);
			table.insert(self._newbullet, bullet);
			table.insert(playerbullet, bullet);
		end
	end	
	for i, plane in pairs(self._playerplane) do
		if not plane:getFitState() and not plane:getStartFitState() and plane:isFire() then
			self._bulletinx = self._bulletinx + 1
			local bullet = Bullet.new(self._bulletinx)
			local info = plane:getInfo();
			local pos = {
				x = info.posX,
				y = info.posY + info.height + 30,
			}
			local endpos = {
				x = info.posX, 
				y = 1650,
			}
			bullet:setPositon(pos);
			bullet:setEndPositon(endpos);
			bullet:setType(0);
			bullet:setBulletData(BulletCfg[1].bullettype)
			bullet:setPlayerBulletIdx(plane:getInfo().idx)
			
			local selfplaneaction = {}
			for ia, action in pairs(BulletTypeCfg[1].actiontype) do
				local ta = {
					actiontype = action.actionenum,
					startpos = { nXpos = action.startpos.x, nYpos = action.startpos.y },
					endpos = { nXpos = action.endpos.x, nYpos = action.endpos.y },
					nangle = action.angle,
				}
				table.insert(selfplaneaction, ta)
			end
			if selfplaneaction and #selfplaneaction > 0 then
				selfplaneaction[1].startpos = { nXpos = pos.x, nYpos = pos.y }
				selfplaneaction[1].endpos = { nXpos = pos.x, nYpos = 1400 }
			end
			bullet:setActionArray(selfplaneaction)
			table.insert(self._bullet, bullet);
			table.insert(self._newbullet, bullet);
			table.insert(playerbullet, bullet);
		end
	end
	--敌机子弹
	for i, enemy in pairs(self._enemyplane) do
		if enemy:isFire() then
			self._bulletinx = self._bulletinx + 1
			local bullet = Bullet.new(self._bulletinx)
			local info = enemy:getInfo();
			local pos = {
				x = info.posX,
				y = info.posY - info.height - 30,
			}
			local endpos = {
				x = info.posX, 
				y = -200,
			}
			bullet:setPositon(pos);
			bullet:setEndPositon(endpos);
			bullet:setSpeed(20);
			bullet:setAngle(-90);
			bullet:setType(1);
			--print("setEnemyBulletIdx ".. enemy:getInfo().idx)
			bullet:setEnemyBulletIdx(enemy:getInfo().idx)
			local bulletAction = enemy:getCurrBulletData()
			bullet:setBulletData(bulletAction.bullet);
			
			local selfplaneaction = {}
			for ia, action in pairs(bulletAction.bulletacttype) do
				local ta = {
					actiontype = action.actionenum,
					startpos = { nXpos = action.startpos.x, nYpos = action.startpos.y },
					endpos = { nXpos = action.endpos.x, nYpos = action.endpos.y },
					nangle = action.angle,
				}
				-- 如果是指定项子弹，终点就是玩家飞机的位置
				if action.actionenum == 2 then
					-- 随机挑选一只玩家飞机
					local randomindex = random(1, #self._playerplane);
					if self._playerplane[randomindex] then
						ta.endpos.nXpos = self._playerplane[randomindex]:getInfo().posX;
						ta.endpos.nYpos = self._playerplane[randomindex]:getInfo().posY;
						ta.nangle = ( Math.atan2((ta.endpos.nXpos - ta.startpos.nXpos) , (ta.endpos.nYpos - ta.startpos.nYpos)) ) * ( 180 / Math.PI);
						-- 进行远方向延伸,y抽
						if ta.endpos.nYpos > ta.startpos.nYpos then
							ta.endpos.nXpos = Math.tan(ta.nangle / 180 * Math.PI ) * (1400 - ta.startpos.nYpos);
							ta.endpos.nYpos = 1400;
						elseif ta.endpos.nYpos == ta.startpos.nYpos then
							if ta.endpos.nXpos >= ta.startpos.nXpos then
								ta.endpos.nXpos = 850
							else 
								ta.endpos.nXpos = -200
							end
						else
							ta.endpos.nXpos = Math.tan(ta.nangle / 180 * Math.PI ) * ( ta.startpos.nYpos - (-200));
							ta.endpos.nYpos = -200;
						end
					end
				end
				table.insert(selfplaneaction, ta)
			end
			if selfplaneaction and #selfplaneaction > 0 then
				selfplaneaction[1].startpos = { nXpos = pos.x, nYpos = pos.y }
				selfplaneaction[1].endpos = { nXpos = endpos.x, nYpos = endpos.y }
			end
			
			bullet:setActionArray(selfplaneaction)
			table.insert(self._bullet, bullet);
			table.insert(self._newbullet, bullet);
			table.insert(playerbullet, bullet);
		end
	end
	if #playerbullet > 0 then
		self:sendBulletEvent(0, playerbullet)
		self._bhaveNewBullet = true;
	end
end

local function sendEnemyMoveEvent(self)
	-- 是否有新的一波
	self._bhavemove = false;
	local enemymovearray = {}
	for i, e in pairs(self._enemyplane) do
		
		local info = e:getInfo()
		local enemyAirPlaneMove = {}
		enemyAirPlaneMove.idx = info.idx
		enemyAirPlaneMove.moveaction = e:getActionArray()
		table.insert(enemymovearray, enemyAirPlaneMove)
	end
	
	self:sendEnemyEvent(1, {}, enemymovearray);
end

local function sendBulletMoveEvent(self)
	-- 是否有新的一波
	self._bhaveNewBullet = false;
	local bulletmovearray = {}
	for i, b in pairs(self._newbullet) do
		local info = b:getInfo()
		local bulletMove = {}
		bulletMove.idx = info.idx
		bulletMove.actiontype = b:getActionArray()
		table.insert(bulletmovearray, bulletMove)
	end
	self._newbullet = {}
	self:sendBulletEvent(1, {}, bulletmovearray);
end

local function sendFitPlaneEvent(self, ntype)
	-- 是否有新的一波
	self._bhaveNewBullet = false;
	local bulletmovearray = {}
	for i, b in pairs(self._newbullet) do
		local info = b:getInfo()
		local bulletMove = {}
		bulletMove.idx = info.idx
		bulletMove.actiontype = b:getActionArray()
		table.insert(bulletmovearray, bulletMove)
	end
	self._newbullet = {}
	self:sendBulletEvent(1, {}, bulletmovearray);
end

--检查合体
function PokeServer:startCheckFit()
	-- 循环每个玩家飞机,判断合体
	local fitPlane = {}
	local existPlane = {}
	local startFitPlane = {}
	for i, planei in pairs(self._playerplane) do
		if not planei:getFitState() and not planei:isOut() then
			local tempPlane = {}
			for j , planej in pairs(self._playerplane) do
				if not planej:getFitState() and not planej:isOut() then
					local bExist = false;
					for ij , planez in pairs(existPlane) do
						if planez == planej then
							bExist = true;
							break;
						end
					end
					if i ~= j and not bExist then
						-- 先判断是否距离足够，然后再判断进入合体开始阶段，上面判断过合体状态了，不需要再判断
						if CollisionTool:judgeFit(planei,planej) then
							-- 开始合体
							if planei:getStartFitState() and planej:getStartFitState() then
								-- 已经再合体状态中了，加时间
								if planei:addFitTime() then
									if #tempPlane == 0 then
										table.insert(tempPlane, planei);
										planei:setFitState(true)
									end
									table.insert(tempPlane, planej);
									planej:setFitState(true)
								end
							else
								--没有合体，需要激活合体时间
								planei:setStartFitState(true)
								planei:setFitTime(0)
								planej:setStartFitState(true)
								planej:setFitTime(0)
								table.insert(startFitPlane, planei)
								table.insert(startFitPlane, planej)
							end
							
						end
					end
				end
			end
			table.insert(existPlane, planei);
			if #tempPlane > 0 then
				table.insert(fitPlane, tempPlane);
			end
		end
	end
	-- 合体开始事件
	if #startFitPlane > 0 then
		print("start fitplane")
		self:sendPlaneEvent(4, startFitPlane, 2)
	end
	-- 创建合体机
	if #fitPlane > 0 then
		local fitplanearray = {}
		for i, planeArray in pairs(fitPlane) do
			print("create fit plane");
			self:createFitPlane(planeArray);
			-- 发送飞机合体事件
			self:sendPlaneEvent(2, planeArray);
		end
	end
	-- 结束合体过程
	local cancelFitPlane = {}
	for i, planei in pairs(self._playerplane) do
		if planei:getStartFitState() and not planei:isOut() then
			local bExistFit = false;
			for j , planej in pairs(self._playerplane) do
				if planej:getStartFitState() and not planej:isOut() then
					if planei ~= planej then
						-- 先判断是否距离足够，然后再判断进入合体开始阶段，上面判断过合体状态了，不需要再判断
						if CollisionTool:judgeFit(planei,planej) then
							bExistFit = true;
						end
					end
				end
			end
			if not bExistFit then
				table.insert(cancelFitPlane, planei);
				planei:setStartFitState(false);
				planei:setFitTime(0);
			end
		end
		table.insert(existPlane, planei);
	end
	if #cancelFitPlane > 0 then
		print("cancel fitplane")
		self:sendPlaneEvent(5, cancelFitPlane);
	end
	--解体
	local remArray = {}
	local rmArray = {}
	-- 合体机移动队列
	local fitPlaneMoveArray  = {}
	for i, fitPlane in pairs(self._fitplane) do
		local fitarray = fitPlane:getFitArray();
		local planeArray = {}
		for z ,fitIdx in pairs(fitarray) do
			for j, plane in pairs(self._playerplane) do
				if plane:getInfo().idx == fitIdx then
					table.insert(planeArray, plane);
					break;
				end
			end
		end
		-- 判断是否全部飞机都满足距离
		local bFit = true;
		for j, plane in pairs(planeArray) do
			local bExist = false;
			for z ,planez in pairs(planeArray) do
				if i ~= z and CollisionTool:judgeFit(plane, planez) then
					bExist = true;
				end
			end
			if not bExist then
				bFit = false;
			end
		end
		-- 是否需要解体
		if not bFit then
			--需要解体
			table.insert(rmArray, fitPlane);
			table.insert(remArray, i);
		else 
			-- 更新具体合体机的位置
			local posX = 0;
			local posY = 0;
			for j, plane in pairs(planeArray) do
				posX = posX + plane:getInfo().posX;
				posY = posY + plane:getInfo().posY;
			end
			if planeArray and #planeArray > 0 then
				local oldPosX = fitPlane:getPosition().nXpos
				local oldPosY = fitPlane:getPosition().nYpos
				posX = posX / #planeArray;
				posY = posY / #planeArray;
				fitPlane:setPositon({nXpos = posX, nYpos = posY });
				if oldPosX ~= posX or 
					oldPosY ~= posY then
					table.insert(fitPlaneMoveArray, fitPlane);
				end
			end
		end
	end
	for i = #remArray , 1, -1 do
		table.remove(self._fitplane,remArray[i]);
	end
	-- 发送解体
	if rmArray and #rmArray > 0 then
		-- 复位小飞机的状态
		for i, fitplane in pairs(rmArray) do
			local fitarray = fitplane:getFitArray();
			for z ,fitIdx in pairs(fitarray) do
				for j, plane in pairs(self._playerplane) do
					if plane:getInfo().idx == fitIdx then
						plane:setFitState(false)
						break;
					end
				end
			end
		end
		self:sendFitPlaneEvent(3, rmArray);
	end
	-- 合体机移动
	if fitPlaneMoveArray and #fitPlaneMoveArray > 0 then
		self:sendFitPlaneEvent(1, fitPlaneMoveArray);
	end
end

-- 创建合体机，通过子飞机的配置
function PokeServer:createFitPlane(playeArray)
	local posX = 0;
	local posY = 0;
	-- 攻击力，防御力，血量
	local attack = 0;
	local defensive = 0;
	local blood = 0;
	local planeIdxArray = {};
	local width = 0;
	local height = 0;
	for i, planeTmp in pairs(playeArray) do
		posX = posX + planeTmp:getInfo().posX;
		posY = posY + planeTmp:getInfo().posY;
		attack = attack + planeTmp:getInfo().attack;
		defensive = defensive + planeTmp:getInfo().defensive;
		blood = blood + planeTmp:getInfo().blood;
		table.insert(planeIdxArray, planeTmp:getInfo().idx);
		if width ~= 0 then
			width = planeTmp:getInfo().width * 1.5;
			height = planeTmp:getInfo().height * 1.5;
		end
	end
	if #playeArray > 0 then
		posX = math.floor(posX / #playeArray)
		posY = math.floor(posY / #playeArray)
	end
	local fitplanetype = FitPlaneCfg[1].fitplanetype
	local planeData = {
		posX = posX,
		posY = posY,
		attack = attack,
		defensive = defensive,
		blood = blood,
		width = fitplanetype.size.width,
		height = fitplanetype.size.height,
		firetime = fitplanetype.firetime,
		bullet = fitplanetype.bullet,
		bulletacttype = fitplanetype.bulletacttype,
	}
	self._fitplaneinx = self._fitplaneinx + 1 
	local fitplane = FitPlane.new(self._fitplaneinx, planeIdxArray)
	fitplane:setPlaneData(planeData);
	table.insert(self._fitplane, fitplane)
	
	local tFitPlane = {}
	table.insert(tFitPlane, fitplane);
	self:sendFitPlaneEvent(0, tFitPlane)
end

-- 移动，0.5s动一次
local moveDely = 0
function PokeServer:startMove()
	moveDely = moveDely + 0.1
	if moveDely >= 0.1 then
		moveDely = 0;
		-- 发送移动事件
		if self._bhavemove then
			sendEnemyMoveEvent(self);
		end
		
		if self._bhaveNewBullet then
			sendBulletMoveEvent(self);
		end
		
		-- 敌机
		local remEnemyArray = {}
		for i , enemyplane in pairs(self._enemyplane) do
			enemyplane:move();
			if enemyplane:judgeOut() then
				table.insert(remEnemyArray, i);
			end
		end
		for i = #remEnemyArray , 1, -1 do
			--print("remove before enemy size = " .. #self._enemyplane)
			table.remove(self._enemyplane,remEnemyArray[i]);
			--print("remove after enemy size = " .. #self._enemyplane)
		end
		local remArray = {}
		for i, bullet in pairs(self._bullet) do
			bullet:move();
			if bullet:judgeOut() then
				table.insert(remArray, i);
			end
		end
		for i = #remArray , 1, -1 do
			table.remove(self._bullet,remArray[i]);
		end
	end
end

-- 检测碰撞
function PokeServer:startCheckCollision()
	-- 消亡的子弹
	local destoryBullet = {}
	-- 消亡的敌机
	local destoryEnemyPlane = {}
	-- 受伤的敌机
	local injuredEnemyPlane = {}
	-- 受伤的玩家的飞机
	local injuredSelfPlane = {}
	-- 消亡的玩家飞机
	local destorySelfPlane = {}
	-- 受伤的和体积的飞机
	local injuredFitPlane = {}
	-- 消亡的合体机飞机
	local destoryFitPlane = {}
	-- 合体的飞机
	for i, fitplane in pairs(self._fitplane) do
		local remArray = {}
		local remEnemyArray = {}
		for j, bullet in pairs(self._bullet) do
			if bullet:getInfo().enemyindex > 0 then
				if CollisionTool:judgeCollision(fitplane:getInfo(),bullet:getInfo()) then
					-- 中了
					table.insert(remArray, j);
					local dataT = fitplane:injured(bullet:getInfo());
					if not dataT.bExist then
						-- 合体机死亡，代表的是组成的所有小飞机死亡
						for p,pidx in pairs(fitplane:getFitArray()) do
							for ii, plane in pairs(self._playerplane) do 
								if plane:getInfo().idx == pidx then
									plane:playerOut();
									table.insert(destorySelfPlane, plane);
									break;
								end
							end
						end
						table.insert(destoryFitPlane, fitplane);
					end
					for p,pidx in pairs(fitplane:getFitArray()) do
						for ii, plane in pairs(self._playerplane) do 
							if plane:getInfo().idx == pidx then
								plane:injuredByFitPlane(dataT.disblood / 2);
								plane.disblood = dataT.disblood / 2;
								table.insert(injuredSelfPlane, plane);
								break;
							end
						end
					end
					fitplane.disblood = dataT.disblood 
					table.insert(injuredFitPlane, fitplane)
				end
			end
		end
		-- 敌机，撞到直接减攻击力的血量，敌机直接死，boss机除外
		for j, enemyplane in pairs(self._enemyplane) do
			if CollisionTool:judgeCollision(fitplane:getInfo(),enemyplane:getInfo()) then
				-- 撞到
				table.insert(remEnemyArray, j);
				local dataT = fitplane:injured(enemyplane:getInfo());
				if not dataT.bExist then
					-- 合体机死亡，代表的是组成的所有小飞机死亡
					for p,pidx in pairs(fitplane:getFitArray()) do
						for ii, plane in pairs(self._playerplane) do 
							if plane:getInfo().idx == pidx then
								plane:playerOut();
								table.insert(destorySelfPlane, plane);
								break;
							end
						end
					end
					table.insert(destoryFitPlane, fitplane);
				end
				fitplane.disblood = dataT.disblood
				table.insert(injuredFitPlane, fitplane)
			end
		end
			
		for i = #remArray , 1, -1 do
			table.insert(destoryBullet,self._bullet[remArray[i]]);
			table.remove(self._bullet,remArray[i]);
		end
		
		-- 删除撞到的敌机
		for i = #remEnemyArray , 1, -1 do
			table.insert(destoryEnemyPlane,self._enemyplane[remEnemyArray[i]]);
			table.remove(self._enemyplane,remEnemyArray[i]);
		end
	end
	-- 自己的飞机
	for i, plane in pairs(self._playerplane) do
		-- 撞敌机
		-- 撞敌人的子弹 击中 则子弹销毁，自己飞机减血
		-- 合体中的小飞机是隐身状态，不计算碰撞
		if not plane:getFitState() and not plane:isOut() then
			local remArray = {}
			local remEnemyArray = {}
			-- 敌人的子弹
			for j, bullet in pairs(self._bullet) do
				if bullet:getInfo().enemyindex > 0 then
					if CollisionTool:judgeCollision(plane:getInfo(),bullet:getInfo()) then
						-- 中了
						table.insert(remArray, j);
						local dataT = plane:injured(bullet:getInfo());
						if not dataT.bExist then
							-- 玩家死亡
							plane:playerOut();
							table.insert(destorySelfPlane, plane);
						end
						plane.disblood = dataT.disblood
						table.insert(injuredSelfPlane, plane)
					end
				end
			end
			-- 敌机，撞到直接减攻击力的血量，敌机直接死，boss机除外
			for j, enemyplane in pairs(self._enemyplane) do
				if CollisionTool:judgeCollision(plane:getInfo(),enemyplane:getInfo()) then
					-- 撞到
					table.insert(remEnemyArray, j);
					local dataT = plane:injured(enemyplane:getInfo());
					if not dataT.bExist then
						-- 玩家死亡
						plane:playerOut();
						table.insert(destorySelfPlane, plane);
					end
					plane.disblood = dataT.disblood
					table.insert(injuredSelfPlane, plane)
				end
			end
			for i = #remArray , 1, -1 do
				table.insert(destoryBullet,self._bullet[remArray[i]]);
				table.remove(self._bullet,remArray[i]);
			end
			-- 删除撞到的敌机
			for i = #remEnemyArray , 1, -1 do
				table.insert(destoryEnemyPlane,self._enemyplane[remEnemyArray[i]]);
				table.remove(self._enemyplane,remEnemyArray[i]);
			end
		end
	end
	-- 敌机
	local remEnemyArray = {}
	for i, enemy in pairs(self._enemyplane) do
		-- 撞子弹
		local remArray = {}
		for j, bullet in pairs(self._bullet) do
			
			if bullet:getInfo().playerindex > 0 or bullet:getInfo().fitplayerindex > 0 then
				if CollisionTool:judgeCollision(enemy:getInfo(),bullet:getInfo()) then
					-- 中了
					table.insert(remArray, j);
					local dataT = enemy:injured(bullet:getInfo())
					-- 发送受伤的
					if not dataT.bExist then
						table.insert(remEnemyArray,i);
					end
					enemy.disblood = dataT.disblood
					table.insert(injuredEnemyPlane, enemy)
				end
			end
		end
		for i = #remArray , 1, -1 do
			table.insert(destoryBullet,self._bullet[remArray[i]]);
			table.remove(self._bullet,remArray[i]);
		end
	end
	for i = #remEnemyArray , 1, -1 do
		table.insert(destoryEnemyPlane,self._enemyplane[remEnemyArray[i]]);
		table.remove(self._enemyplane,remEnemyArray[i]);
	end
	-- 合体机
	for i, fitplane in pairs(self._fitplane) do
		-- 撞敌人的子弹 击中 则子弹销毁，自己飞机减血
		local remArray = {}
		for j, bullet in pairs(self._bullet) do
			if bullet:getInfo().enemyindex > 0 then
				if CollisionTool:judgeCollision(fitplane:getInfo(),bullet:getInfo()) then
					-- 中了
					table.insert(remArray, j);
					local dataT = fitplane:injured(bullet:getInfo());
					-- 这边还要扣分体机的血量
					if not dataT.bExist then
						table.insert(destoryFitPlane, fitplane);
					end
					fitplane.disblood = dataT.disblood
					table.insert(injuredFitPlane, fitplane)
				end
			end
		end
		for i = #remArray , 1, -1 do
			table.insert(destoryBullet,self._bullet[remArray[i]]);
			table.remove(self._bullet,remArray[i]);
		end
	end
	-- 发送玩家飞机受伤的事件
	if injuredSelfPlane and #injuredSelfPlane > 0 then
		self:sendPlaneEvent(0, injuredSelfPlane);
	end
	-- 发送敌机受伤的事件
	if injuredEnemyPlane and #injuredEnemyPlane > 0 then
		self:sendEnemyEvent(2, injuredEnemyPlane);
	end
	-- 发送子弹消亡事件
	if destoryBullet and #destoryBullet > 0 then
		self:sendBulletEvent(3, destoryBullet);
	end
	-- 发送敌机消亡事件
	if destoryEnemyPlane and #destoryEnemyPlane > 0 then
		self:sendEnemyEvent(3, destoryEnemyPlane)
	end
	-- 发送玩家消亡事件
	if destorySelfPlane and #destorySelfPlane > 0 then
		self:sendPlaneEvent(1, destorySelfPlane);
	end
	-- 发送合体减血事件
	if injuredFitPlane and #injuredFitPlane > 0 then
		self:sendFitPlaneEvent(2, injuredFitPlane);
	end
	-- 发送合体消亡事件
	if destoryFitPlane and #destoryFitPlane > 0 then
		self:sendFitPlaneEvent(3, destoryFitPlane);
	end
end

function PokeServer:startNextStep()
	-- 判断是否还存有飞机，假如不存在，则下一波开始
	if self._step ~= 0 and self._enemyplane and #self._enemyplane == 0 then
		if self._nextsteptime > 0 then
			self._nextsteptime = self._nextsteptime - 1;
		else 
			self._bnextstep = true;
		end
		
	end
	--判断是否有新创建的飞机
	if self._bnextstep then
		self._bnextstep = false;
		self._nextsteptime = 100;
		self._step = self._step + 1;
		self:sendGameStep()
		if self._step > #self._stepData then
			self.strongcount = self.strongcount + 1;
			self._step = 1;
		end
		-- 根据配置创建第几波的敌机
		local enemyplanearray = {}
		if self._stepData[self._step] then
			-- 创建敌机
			local stepData = self._stepData[self._step]
			for i, d in pairs(stepData) do
				for i = 1, d.cnt do
					self._enemyinx = self._enemyinx + 1 
					local enemyplane = EnemyPlane.new(self._enemyinx)
					enemyplane:setActionArray(d.planetype)
					enemyplane:setPlaneData(d.plane, self.strongcount);
					table.insert(self._enemyplane, enemyplane)
					table.insert(enemyplanearray, enemyplane)
				end
			end
		end

		self:sendEnemyEvent(0, enemyplanearray)
		self._bhavemove = true;
	end
end

--[[
	作用: 发送游戏事件
	
]]
-- 设置玩家飞机位置
function PokeServer:setPlayerPlanePos(pos, position)
	if not self._playerplane[pos]:isOut() then
		self._playerplane[pos]:setPositon(position)
		for i = 1,maxplayersize do 
			if i ~= pos then
				self._users[i]:sendPlanePostion(pos, position)
			end
		end
	end
end

-- 发送玩家初始飞机的数据
function PokeServer:sendPlayerPlanedata(pos,plane)
	
end

-- 发送合体飞机事件
function PokeServer:sendFitPlaneEvent(eventtype, fitplane)
	for i = 1,maxplayersize do 
		self._users[i]:sendFitPlaneEvent(eventtype, fitplane)
	end
end

-- 发送玩家飞机事件
function PokeServer:sendPlaneEvent(eventtype, plane, ntime)
	for i = 1,maxplayersize do 
		self._users[i]:sendPlaneEvent(eventtype, plane, ntime)
	end
end

-- 发送敌机事件
function PokeServer:sendEnemyEvent(eventtype, enemyplane, eventmove)
	for i = 1,maxplayersize do 
		self._users[i]:sendEnemyEvent(eventtype, enemyplane, eventmove)
	end
end

-- 发送子弹事件
function PokeServer:sendBulletEvent(eventtype, bullet, eventmove)
	for i = 1,maxplayersize do 
		self._users[i]:sendBulletEvent(eventtype, bullet, eventmove)
	end
end

-- 发送游戏整数据
local sendtime = 0
function PokeServer:sendGameData()
	moveDely = moveDely + 1
	if moveDely >= 50 then
		moveDely = 0;
		for i = 1,maxplayersize do 
			self._users[i]:sendGameData(self._enemyplane, self._bullet)
		end
	end
end

-- 发送游戏几波开始
function PokeServer:sendGameStep()
	local count = self.strongcount * self.stepcount + self._step;
	for i = 1,maxplayersize do 
		self._users[i]:sendGameStep(count)
	end
end

function PokeServer:gameOver()
	for i = 1,maxplayersize do 
		self._users[i]:gameOver();
	end
	
	print("poke gameover =" .. self._roomid)
	local room_mgr_addr = skynet.uniqueservice"room_mgr"
	skynet.call(room_mgr_addr,"lua","room_over",self._roomid)
end

function PokeServer.new(...)
	local instance = {}
	setmetatable(instance,PokeServer_mt)
	instance:ctor(...)
	return instance
end

return PokeServer
